package nio.test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * @Author: admin
 * @Description:
 * @Date: 2018/9/28 17:59
 */

public class NioSocketServer implements Runnable {
    private int port;
    private ByteBuffer echoBuffer = ByteBuffer.allocate( 1024 );

    public NioSocketServer(int port) {
        this.port = port;
    }

    @Override
    public void run() {
        try {
            Selector selector = Selector.open();
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.configureBlocking(false);

            ServerSocket serverSocket = serverSocketChannel.socket();
            InetSocketAddress inetSocketAddress = new InetSocketAddress(port);
            serverSocket.bind(inetSocketAddress);

            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

            System.out.println("Going to listen on " + port);

            while (true) {
                int num = selector.select();
                Iterator iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()) {
                    SelectionKey key = (SelectionKey) iterator.next();
                    if(key.isAcceptable()){
                        ServerSocketChannel ssc=(ServerSocketChannel) key.channel();
                        SocketChannel sc=ssc.accept();
                        sc.configureBlocking(false);
                        sc.register(selector,SelectionKey.OP_READ);
                    }else if(key.isReadable()){
                        SocketChannel sc=(SocketChannel) key.channel();
                        int bytesEchoed=0;
                        StringBuffer sb = new StringBuffer();
                        echoBuffer.clear();
                        int r=0;
                        while ((r=sc.read(echoBuffer))>0){
                            echoBuffer.flip();
                            byte[] bs=new byte[r];
                            echoBuffer.get(bs,0,r);
                            sb.append(new String(bs));
                            echoBuffer.clear();
                        }
                        //if(-1==r) sc.close();
                        System.out.println( "Echoed "+bytesEchoed+" from "+sc +sb.toString());
                        sc.write(ByteBuffer.wrap("hello 123".getBytes()));
                    }
                    iterator.remove();
//                    if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {
//                        ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
//                        SocketChannel sc = ssc.accept();
//                        sc.configureBlocking(false);
//
//                        sc.register(selector,SelectionKey.OP_READ);
//
//                    }else if((key.readyOps()&SelectionKey.OP_READ)==SelectionKey.OP_READ){
//                        SocketChannel sc=(SocketChannel) key.channel();
//                        int bytesEchoed=0;
//                        while (true){
//                            echoBuffer.clear();
//                            int r=sc.read(echoBuffer);
//                            if(r<=0) break;
//                            echoBuffer.flip();
//                            sc.write( echoBuffer );
//                            bytesEchoed += r;
//                        }
//                        System.out.println( "Echoed "+bytesEchoed+" from "+sc );
//                    }
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args){
        new Thread(new NioSocketServer(9999)).start();
    }
}
